﻿//-----------------------------------------------------------------------
// <copyright>
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
// </copyright>
//----------------------------------------------------------------------- 
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Threading;

namespace Fulcrum.DispatcherProxies
{
    static class DispatcherProxyGenerationPolicy
    {
        public static bool IsProxyableType(Type type)
        {
            // TODO Add support to proxy public nested classes
            if (type.IsPublic && (type.IsSubclassOf(typeof(DispatcherObject)) || type.Equals(typeof(DispatcherObject))))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static bool AreParametersSupported(ICollection<ParameterInfo> parameters)
        {
            foreach (var param in parameters)
            {
                if (false == IsParameterSupported(param))
                {
                    return false;
                }
            }

            return true;
        }

        static bool IsParameterSupported(ParameterInfo param)
        {
            //
            // TODO: out and ref parameters aren't supported yet.
            //
            if (((param.Attributes & ParameterAttributes.Out) == ParameterAttributes.Out) ||
                param.ParameterType.IsByRef)
            {
                return false;
            }

            return true;
        }

        public static bool IsSupportedMethod(MethodInfo method)
        {
            //
            // The proxy doesn't wrap some methods
            //
            if (method.Name.Equals("GetType", StringComparison.InvariantCulture))
            {
                return false;
            }

            //
            // The get_ and set_ methods aren't supported as methods.
            //
            if ((method.Attributes & MethodAttributes.SpecialName) == MethodAttributes.SpecialName)
            {
                return false;
            }

            //
            // Methods w/ generic parameters are not supported yet.
            //
            if (method.ContainsGenericParameters)
            {
                return false;
            }

            return AreParametersSupported(method.GetParameters());
        }

    }
}
